﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ImageAnalysis;
using System.IO;
using HCSAnalyzer.ObjectForNotations;
using HCSAnalyzer.Classes;
using HCSAnalyzer.Classes.MetaComponents;
using HCSAnalyzer.Classes.Base_Classes.Viewers;
using HCSAnalyzer.Classes.Base_Classes.DataStructures;
using HCSAnalyzer.Classes.Base_Classes.DataAnalysis;
using ImageAnalysisFiltering;
using HCSAnalyzer.Classes.Base_Classes;
using HCSAnalyzer.Classes.ImageAnalysis.FormsForImages;
using System.Drawing.Imaging;
using HCSAnalyzer.Classes._3D;
using HCSAnalyzer.Classes.ImageAnalysis._3D_Engine;

namespace HCSAnalyzer.Forms.FormsForImages
{
    public partial class FormForImageDisplay : Form
    {
        public FormForLUTManager LUTManager = null;
        public FormForNavigator ZNavigator = null;

        public cImage AssociatedImage { get; private set; }
        int Zoom = 100;
        //int ZPos = 0;// 36;
        protected int ViewDimX;
        protected int ViewDimY;
        int StartViewX = 0;
        int StartViewY = 0;

        protected Graphics ThisGraph;
        protected Bitmap BT = null;

        public Bitmap GetBitmap()
        {
            return BT;
        }

        public cGlobalInfo GlobalInfo;


        protected override void OnFormClosing(FormClosingEventArgs e)
        {

            AssociatedImage.Dispose();

            base.OnFormClosing(e);
        }


        public void Unsafe_SetAssociatedImage(cImage Im)
        {
            this.AssociatedImage = Im;
        }

        protected FormForImageDisplay()
        {
            InitializeComponent();

            this.DoubleBuffered = true;

            #region Initialize context Menu
            ContextMenuStrip ImageContextMenu = new ContextMenuStrip();

            ToolStripMenuItem ToolStripMenuItem_DisplayHistograms = new ToolStripMenuItem("Histograms");
            ImageContextMenu.Items.Add(ToolStripMenuItem_DisplayHistograms);
            ToolStripMenuItem_DisplayHistograms.Click += new System.EventHandler(this.ToolStripMenuItem_DisplayHistograms);

            ToolStripMenuItem ToolStripMenuItem_DisplayAS = new ToolStripMenuItem("Display as...");

            ToolStripMenuItem ToolStripMenuItem_DisplayDataTable = new ToolStripMenuItem("Data Table");
            ToolStripMenuItem_DisplayAS.DropDownItems.Add(ToolStripMenuItem_DisplayDataTable);
            ToolStripMenuItem_DisplayDataTable.Click += new System.EventHandler(this.ToolStripMenuItem_DisplayDataTable);

            //ToolStripMenuItem ToolStripMenuItem_DisplayElevationMap = new ToolStripMenuItem("Elevation Map");
            //ToolStripMenuItem_DisplayAS.DropDownItems.Add(ToolStripMenuItem_DisplayElevationMap);
            //ToolStripMenuItem_DisplayElevationMap.Click += new System.EventHandler(this.DisplayElevationMap);

            ImageContextMenu.Items.Add(ToolStripMenuItem_DisplayAS);

            ToolStripMenuItem ToolStripMenuItem_ImageProcessing = new ToolStripMenuItem("Image Processing");

            ToolStripMenuItem ToolStripMenuItem_Filtering = new ToolStripMenuItem("Filtering");

            ToolStripMenuItem ToolStripMenuItem_Filtering_GaussianConvolution = new ToolStripMenuItem("Gaussian Convolution");
            ToolStripMenuItem_Filtering.DropDownItems.Add(ToolStripMenuItem_Filtering_GaussianConvolution);
            ToolStripMenuItem_Filtering_GaussianConvolution.Click += new System.EventHandler(this.ToolStripMenuItem_Filtering_GaussianConvolution);

            ToolStripMenuItem ToolStripMenuItem_Filtering_Median = new ToolStripMenuItem("Median (x5)");
            ToolStripMenuItem_Filtering.DropDownItems.Add(ToolStripMenuItem_Filtering_Median);
            ToolStripMenuItem_Filtering_Median.Click += new System.EventHandler(this.ToolStripMenuItem_Filtering_Median);

            ToolStripMenuItem_Filtering.DropDownItems.Add(new ToolStripSeparator());

            ToolStripMenuItem ToolStripMenuItem_Morpho_Erode = new ToolStripMenuItem("Erode (x3)");
            ToolStripMenuItem_Filtering.DropDownItems.Add(ToolStripMenuItem_Morpho_Erode);
            ToolStripMenuItem_Morpho_Erode.Click += new System.EventHandler(this.ToolStripMenuItem_Morpho_Erode);

            ToolStripMenuItem ToolStripMenuItem_Morpho_Dilate = new ToolStripMenuItem("Dilate (x3)");
            ToolStripMenuItem_Filtering.DropDownItems.Add(ToolStripMenuItem_Morpho_Dilate);
            ToolStripMenuItem_Morpho_Dilate.Click += new System.EventHandler(this.ToolStripMenuItem_Morpho_Dilate);

            ToolStripMenuItem_ImageProcessing.DropDownItems.Add(ToolStripMenuItem_Filtering);

            ToolStripMenuItem ToolStripMenuItem_Edges = new ToolStripMenuItem("Edge Detection");

            ToolStripMenuItem ToolStripMenuItem_Edges_Canny = new ToolStripMenuItem("Canny (10,60)");
            ToolStripMenuItem_Edges.DropDownItems.Add(ToolStripMenuItem_Edges_Canny);
            ToolStripMenuItem_Edges_Canny.Click += new System.EventHandler(this.ToolStripMenuItem_Edges_Canny);
            ToolStripMenuItem_Edges_Canny.Enabled = false;

            ToolStripMenuItem ToolStripMenuItem_Edges_Sobel = new ToolStripMenuItem("Sobel (1,1,3)");
            ToolStripMenuItem_Edges.DropDownItems.Add(ToolStripMenuItem_Edges_Sobel);
            ToolStripMenuItem_Edges_Sobel.Click += new System.EventHandler(this.ToolStripMenuItem_Edges_Sobel);

            ToolStripMenuItem ToolStripMenuItem_Edges_Laplace = new ToolStripMenuItem("Laplace (x3)");
            ToolStripMenuItem_Edges.DropDownItems.Add(ToolStripMenuItem_Edges_Laplace);
            ToolStripMenuItem_Edges_Laplace.Click += new System.EventHandler(this.ToolStripMenuItem_Edges_Laplace);

            ToolStripMenuItem_ImageProcessing.DropDownItems.Add(ToolStripMenuItem_Edges);

            ToolStripMenuItem ToolStripMenuItem_GeometricalManip = new ToolStripMenuItem("Geometrical Processings");

            ToolStripMenuItem ToolStripMenuItem_GeometricalResize = new ToolStripMenuItem("Resize");
            ToolStripMenuItem_GeometricalManip.DropDownItems.Add(ToolStripMenuItem_GeometricalResize);
            ToolStripMenuItem_GeometricalResize.Click += new System.EventHandler(this.ToolStripMenuItem_GeometricalResize);

            ToolStripMenuItem_ImageProcessing.DropDownItems.Add(ToolStripMenuItem_GeometricalManip);

            ToolStripMenuItem ToolStripMenuItem_Segmentation = new ToolStripMenuItem("Segmentation");

            ToolStripMenuItem ToolStripMenuItem_SegmentationThreshold = new ToolStripMenuItem("Threshold");
            ToolStripMenuItem_Segmentation.DropDownItems.Add(ToolStripMenuItem_SegmentationThreshold);
            ToolStripMenuItem_SegmentationThreshold.Click += new System.EventHandler(this.ToolStripMenuItem_SegmentationThreshold);

            ToolStripMenuItem ToolStripMenuItem_SegmentationKMeans = new ToolStripMenuItem("K-Means");
            ToolStripMenuItem_Segmentation.DropDownItems.Add(ToolStripMenuItem_SegmentationKMeans);
            ToolStripMenuItem_SegmentationKMeans.Click += new System.EventHandler(this.ToolStripMenuItem_SegmentationKMeans);

            ToolStripMenuItem ToolStripMenuItem_FindContours = new ToolStripMenuItem("Find Contours");
            ToolStripMenuItem_Segmentation.DropDownItems.Add(ToolStripMenuItem_FindContours);
            ToolStripMenuItem_FindContours.Click += new System.EventHandler(this.ToolStripMenuItem_FindContours);

            ToolStripMenuItem ToolStripMenuItem_SegmentationMeanShift = new ToolStripMenuItem("Mean Shift");
            ToolStripMenuItem_Segmentation.DropDownItems.Add(ToolStripMenuItem_SegmentationMeanShift);
            ToolStripMenuItem_SegmentationMeanShift.Click += new System.EventHandler(this.ToolStripMenuItem_SegmentationMeanShift);
            //ToolStripMenuItem_SegmentationMeanShift.Enabled = false;

            ToolStripMenuItem_ImageProcessing.DropDownItems.Add(ToolStripMenuItem_Segmentation);

            ToolStripMenuItem ToolStripMenuItem_Transforms = new ToolStripMenuItem("Transforms");

            ToolStripMenuItem ToolStripMenuItem_TransformsDistanceMap = new ToolStripMenuItem("Distance Map (L2)");
            ToolStripMenuItem_Transforms.DropDownItems.Add(ToolStripMenuItem_TransformsDistanceMap);
            ToolStripMenuItem_TransformsDistanceMap.Click += new System.EventHandler(this.ToolStripMenuItem_TransformsDistanceMap);

            ToolStripMenuItem ToolStripMenuItem_FindLocalMax = new ToolStripMenuItem("Find Local Max");
            ToolStripMenuItem_Transforms.DropDownItems.Add(ToolStripMenuItem_FindLocalMax);
            ToolStripMenuItem_FindLocalMax.Click += new System.EventHandler(this.ToolStripMenuItem_FindLocalMax);

            ToolStripMenuItem ToolStripMenuItem_AddNoise = new ToolStripMenuItem("Add Gaussian Noise (0-10)");
            ToolStripMenuItem_Transforms.DropDownItems.Add(ToolStripMenuItem_AddNoise);
            ToolStripMenuItem_AddNoise.Click += new System.EventHandler(this.ToolStripMenuItem_AddNoise);

            ToolStripMenuItem_ImageProcessing.DropDownItems.Add(ToolStripMenuItem_Transforms);

            ImageContextMenu.Items.Add(ToolStripMenuItem_ImageProcessing);

            ToolStripMenuItem copyToClipboardToolStripMenuItem = new ToolStripMenuItem("Copy To Clipboard");
            ImageContextMenu.Items.Add(copyToClipboardToolStripMenuItem);
            copyToClipboardToolStripMenuItem.Click += new System.EventHandler(this.copyToClipboardToolStripMenuItem);
            copyToClipboardToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.C;

            ToolStripMenuItem saveAsToolStripMenuItem = new ToolStripMenuItem("Save as...");
           // saveAsToolStripMenuItem.Enabled = false;
            ImageContextMenu.Items.Add(saveAsToolStripMenuItem);
            saveAsToolStripMenuItem.Click += new System.EventHandler(this.saveAsToolStripMenuItem);
            saveAsToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.S;


            ToolStripMenuItem lUTManagerToolStripMenuItem = new ToolStripMenuItem("LUT Manager");
            ImageContextMenu.Items.Add(lUTManagerToolStripMenuItem);
            lUTManagerToolStripMenuItem.Click += new System.EventHandler(this.lUTManagerToolStripMenuItem);

            ToolStripMenuItem NavigatorToolStripMenuItem = new ToolStripMenuItem("Navigator");
            ImageContextMenu.Items.Add(NavigatorToolStripMenuItem);
            NavigatorToolStripMenuItem.Click += new System.EventHandler(this.NavigatorToolStripMenuItem);



            this.panelForImage.ContextMenuStrip = ImageContextMenu;
            this.panelForImage.ContextMenuStrip.BringToFront();

            #endregion
        }

        #region Image processing
        private void ToolStripMenuItem_GeometricalResize(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            cImageGeometricResize GR = new cImageGeometricResize();
            GR.SetInputData(this.AssociatedImage);
            GR.SliceIndex = (int)ZNavigator.numericUpDownZPos.Value;
            GR.InterpolationType = Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR;

            GR.ListProperties.FindByName("Scale").SetNewValue((double)0.5);
            GR.ListProperties.FindByName("Scale").IsGUIforValue = true;
            cFeedBackMessage FeedBackMessage = GR.Run();

            //GlobalInfo.WindowHCSAnalyzer.richTextBoxConsole.AppendText(FeedBackMessage.GetFullFeedBack());
            if (FeedBackMessage.IsSucceed == false) return;
            
            NewView.SetImage(GR.GetOutPut());

            NewView.Display();
        }

        private void ToolStripMenuItem_Edges_Laplace(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            cImageFilterLaplace FL = new cImageFilterLaplace();
            FL.SetInputData(this.AssociatedImage);
            FL.Aperture = 3;
            FL.Run();
            NewView.SetImage(FL.GetOutPut());

            NewView.Display();
        }

        private void ToolStripMenuItem_Edges_Canny(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            cImageFilterCanny FC = new cImageFilterCanny();
            FC.SetInputData(this.AssociatedImage);
            FC.GreyThreshold = 10;
            FC.GreyThresholdLinkin = 60;
            FC.Run();
            NewView.SetImage(FC.GetOutPut());

            NewView.Display();
        }

        private void ToolStripMenuItem_SegmentationThreshold(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            cImageSegmentationThreshold ME = new cImageSegmentationThreshold();
            ME.SetInputData(this.AssociatedImage);
            ME.ListProperties.FindByName("Threshold").SetNewValue((double)100);
            ME.ListProperties.FindByName("Threshold").IsGUIforValue = true;
            ME.IsInvert = true;
            ME.Run();
            NewView.SetImage(ME.GetOutPut());

            NewView.Display();
        }

        private void ToolStripMenuItem_SegmentationKMeans(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            cImageSegmentationKMeans KM = new cImageSegmentationKMeans();

            KM.SetInputData(this.AssociatedImage);
            //ME.IsInvert = true;
            // KM.ListChannelsToBeProcessed = this.AssociatedImage.GetListChannels();
            KM.ListProperties.FindByName("Number of clusters").SetNewValue((int)3);
            KM.ListProperties.FindByName("Number of clusters").IsGUIforValue = true;
            
            KM.Run();
            NewView.SetImage(KM.GetOutPut());

            NewView.Display();
        }

        private void ToolStripMenuItem_FindContours(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            cImageFindContours FC = new cImageFindContours();
            FC.SetInputData(this.AssociatedImage);

            FC.Run();
            NewView.SetImage(FC.GetOutPut());

            NewView.Display();
        }

        private void ToolStripMenuItem_SegmentationMeanShift(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            cImageSegmentationMeanShift MS = new cImageSegmentationMeanShift();
            MS.SetInputData(this.AssociatedImage);
            //ME.IsInvert = true;
            MS.Run();
            NewView.SetImage(MS.GetOutPut());

            NewView.Display();
        }

        private void ToolStripMenuItem_TransformsDistanceMap(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            cImageDistanceMap DM = new cImageDistanceMap();
            DM.SetInputData(this.AssociatedImage);
            DM.DistanceType = Emgu.CV.CvEnum.DIST_TYPE.CV_DIST_L2;
            DM.Run();
            NewView.SetImage(DM.GetOutPut());

            NewView.Display();
        }

        private void ToolStripMenuItem_FindLocalMax(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            cImageFindLocalMax FLM = new cImageFindLocalMax();
            FLM.SetInputData(this.AssociatedImage);
            //FLM.DistanceType = Emgu.CV.CvEnum.DIST_TYPE.CV_DIST_L2;
            FLM.Run();
            NewView.SetImage(FLM.GetOutPut());

            NewView.Display();
        }

        private void ToolStripMenuItem_AddNoise(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            cImageAddNoise AN = new cImageAddNoise();
            AN.SetInputData(this.AssociatedImage);
            AN.DistributionType = Classes.Base_Classes.Data.eRandDistributionType.GAUSSIAN;
            AN.Mean = 0;
            AN.Stdev = 10;
            //FLM.DistanceType = Emgu.CV.CvEnum.DIST_TYPE.CV_DIST_L2;
            AN.Run();
            NewView.SetImage(AN.GetOutPut());

            NewView.Display();
        }

        private void ToolStripMenuItem_Morpho_Erode(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            cImageMorphoErode ME = new cImageMorphoErode();
            ME.SetInputData(this.AssociatedImage);
            ME.Iterations = 3;
            ME.Run();
            NewView.SetImage(ME.GetOutPut());

            NewView.Display();
        }

        private void ToolStripMenuItem_Morpho_Dilate(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            cImageMorphoDilate ME = new cImageMorphoDilate();
            ME.SetInputData(this.AssociatedImage);
            ME.Iterations = 3;
            ME.Run();
            NewView.SetImage(ME.GetOutPut());

            NewView.Display();
        }

        private void ToolStripMenuItem_Edges_Sobel(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            cImageFilterSobel FS = new cImageFilterSobel();
            FS.SetInputData(this.AssociatedImage);
            FS.Aperture = 3;
            FS.X_Order = 1;
            FS.Y_Order = 1;
            FS.Run();
            NewView.SetImage(FS.GetOutPut());

            NewView.Display();
        }

        private void ToolStripMenuItem_Filtering_Median(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            cImageFilterMedian FM = new cImageFilterMedian();
            FM.SetInputData(this.AssociatedImage);

            
            FM.ListProperties.FindByName("Kernel Size").SetNewValue((int)5);
            FM.ListProperties.FindByName("Kernel Size").IsGUIforValue = true;
            cFeedBackMessage FeedBackMessage = FM.Run();

            //GlobalInfo.WindowHCSAnalyzer.richTextBoxConsole.AppendText(FeedBackMessage.GetFullFeedBack());
            if (FeedBackMessage.IsSucceed == false) return;

            NewView.SetImage(FM.GetOutPut());


            NewView.Display();
            //GlobalInfo.DisplayViewer(NewView);
        }

        private void ToolStripMenuItem_Filtering_GaussianConvolution(object sender, EventArgs e)
        {
            cImageViewer NewView = new cImageViewer();

            ImageAnalysisFiltering.cImageFilterGaussianConvolution GaussianBlur = new ImageAnalysisFiltering.cImageFilterGaussianConvolution();
            GaussianBlur.SetInputData(this.AssociatedImage);
            GaussianBlur.ListProperties.FindByName("Kernel Size").SetNewValue((int)3);
            GaussianBlur.ListProperties.FindByName("Kernel Size").IsGUIforValue = true;
            cFeedBackMessage FeedBackMessage = GaussianBlur.Run();
            if (FeedBackMessage.IsSucceed == false) return;
            NewView.SetImage(GaussianBlur.GetOutPut());

            NewView.Display();
        }
        #endregion

        private void ToolStripMenuItem_DisplayHistograms(object sender, EventArgs e)
        {
            cDesignerTab DT = new cDesignerTab();

            cListExtendedTable ListTables = new cListExtendedTable(this.AssociatedImage);

            for (int i = 0; i < ListTables.Count; i++)
            {
                cLinearize LI = new cLinearize();
                LI.SetInputData(ListTables[i]);
                LI.Run();

                cViewerStackedHistogram VH = new cViewerStackedHistogram();
                VH.SetInputData(LI.GetOutPut());
                VH.Title = ListTables[i].Name;
                if (!VH.Run().IsSucceed) return;

                DT.SetInputData(VH.GetOutPut());
            }
            DT.Run();

            cDisplayToWindow MyDisplay = new cDisplayToWindow();
            MyDisplay.SetInputData(DT.GetOutPut());
            MyDisplay.Title = "Histograms(" + this.AssociatedImage.Name + ")";
            MyDisplay.Run();
            MyDisplay.Display();

        }

        private void ToolStripMenuItem_DisplayDataTable(object sender, EventArgs e)
        {
            cDisplayListExtendedTable DLET = new cDisplayListExtendedTable();
            DLET.SetInputData(new Classes.Base_Classes.DataStructures.cListExtendedTable(this.AssociatedImage));
            DLET.Run();
        }

        //private void DisplayElevationMap(object sender, EventArgs e)
        //{
        //    cViewerElevationMap3D VE = new cViewerElevationMap3D();
        //    VE.SetInputData(new Classes.Base_Classes.DataStructures.cListExtendedTable(this.AssociatedImage)[0]);
        //    if (VE.Run().IsSucceed == false) return;

        //    cDesignerSinglePanel CD = new cDesignerSinglePanel();
        //    CD.SetInputData(VE.GetOutPut());
        //    if (CD.Run().IsSucceed == false) return;

        //    cDisplayToWindow CDW = new cDisplayToWindow();
        //    CDW.SetInputData(CD.GetOutPut());
        //    CDW.Title = this.AssociatedImage.Name + " (Channel0) : Elevation Map";
        //    if (CDW.Run().IsSucceed == false) return;
        //    CDW.Display();
        //}

        public void ChangeZoomValue(int NewZoom)
        {
            Zoom = NewZoom;
            if (Zoom < 5) Zoom = 5;
            toolStripStatusLabelForZoom.Text = "Zoom: " + Zoom.ToString() + " %";
            this.StartViewX = this.HorizontalScroll.Value;
            this.StartViewY = this.VerticalScroll.Value;
            DrawPic();
        }

        private void panelForImage_MouseWheel(object sender, MouseEventArgs e)
        {
            Zoom += e.Delta * SystemInformation.MouseWheelScrollLines / 120;
            ChangeZoomValue(Zoom);
        }

        private void panelForImage_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            ChangeZoomValue(100);
        }

        Rectangle mRect;

        private void panelForImage_MouseDown(object sender, MouseEventArgs e)
        {
            mRect = new Rectangle(e.X, e.Y, 0, 0);
            this.Invalidate();
        }

        private void panelForImage_MouseMove(object sender, MouseEventArgs e)
        {   
            if (e.Button == MouseButtons.Left)
            {
                mRect = new Rectangle(mRect.Left, mRect.Top, e.X - mRect.Left, e.Y - mRect.Top);
                this.Invalidate();
                return;
            }

            float ZoomFactor = Zoom / 100.0f;

            int PosX = e.X;
            int PosY = e.Y;
            int PosZ = ZNavigator.trackBarForZPos.Value;

            if ((PosX >= 0) && (PosX < AssociatedImage.Width) && (PosY >= 0) && (PosY < AssociatedImage.Height))
            {
                string FinalText = "[" + (int)(PosX / ZoomFactor) + ":" + (int)(PosY / ZoomFactor) + "] - (";

                for (int IdxChannel = 0; IdxChannel < AssociatedImage.GetNumChannels(); IdxChannel++)
                {
                    float Value = AssociatedImage.SingleChannelImage[IdxChannel].Data[PosX + PosY * AssociatedImage.Width + PosZ*AssociatedImage.SliceSize ];
                    FinalText += Value.ToString("N2") + ";";
                }
                FinalText = FinalText.Remove(FinalText.Length - 1);
                FinalText += ")";

                toolStripStatusLabelForPosition.Text = FinalText;
            }
            else
            {
                toolStripStatusLabelForPosition.Text = "(#,#)";
            }
        }

        private void displayScaleBarToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void copyToClipboardToolStripMenuItem(object sender, EventArgs e)
        {
            if (BT == null) return;
            MemoryStream ms = new MemoryStream();
            Clipboard.SetImage(BT);
        }

        private void saveAsToolStripMenuItem(object sender, EventArgs e)
        {
            cImageToFile IF = new cImageToFile();
            IF.IsDisplayUIForFilePath = true;
            IF.SetInputData(this.AssociatedImage);
            IF.Run();

        }

        //private void toolTip1_Popup(object sender, PopupEventArgs e)
        //{
        //    Point locationOnForm = panelForImage.FindForm().PointToClient(Control.MousePosition);
        //    string TextForToolTip = locationOnForm.X + "x" + locationOnForm.Y;
        //    toolTip1.SetToolTip(panelForImage, TextForToolTip);
        //    // float Value = AssociatedImage.Data[0].Data[PosX + PosY * AssociatedImage.Width];
        //    return;
        //}

        public void DrawPic()
        {
            if (this.LUTManager == null) return;
            if (this.ZNavigator == null) return;


            int ZPos = ZNavigator.trackBarForZPos.Value;

            ThisGraph = panelForImage.CreateGraphics();

            float ZoomFactor = Zoom / 100.0f;
            int NewWidth = (int)(AssociatedImage.Width * ZoomFactor);
            int NewHeight = (int)(AssociatedImage.Height * ZoomFactor);
            panelForImage.Width = NewWidth;
            panelForImage.Height = NewHeight;

            if ((NewHeight == 0) || (NewWidth == 0)) return;

            int PosViewX = (this.Width - NewWidth) / 2;
            int PosViewY = (this.Height - NewHeight) / 2;
            //   panelForImage.Location = new Point(PosViewX,PosViewY);

            BT = new Bitmap(NewWidth, NewHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            // Lock the bitmap's bits.  
            Rectangle rect = new Rectangle(0, 0, NewWidth, NewHeight);
            System.Drawing.Imaging.BitmapData bmpData = BT.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, BT.PixelFormat);

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            int scanline = Math.Abs(bmpData.Stride);

            byte CurrentRed;
            byte CurrentGreen;
            byte CurrentBlue;

            int RealX;
            int RealY;

            int NewStartX = (int)(this.StartViewX / ZoomFactor);
            int NewStartY = (int)(this.StartViewY / ZoomFactor);

            List<float> Min = new List<float>();
            List<float> Max = new List<float>();
            List<double> GammaList = new List<double>();


            for (int IdxChannel = 0; IdxChannel < this.AssociatedImage.GetNumChannels(); IdxChannel++)
            {
                if (this.LUTManager != null)
                {
                    UserControlSingleLUT SingleLUT = (UserControlSingleLUT)this.LUTManager.panelForLUTS.Controls[IdxChannel];

                    Min.Add((float)SingleLUT.numericUpDownMinValue.Value);
                    Max.Add((float)SingleLUT.numericUpDownMaxValue.Value);
                    GammaList.Add((double)SingleLUT.trackBarGamma.Value/100.0);
                }
            }

            #region Obsolete
            // test for new display
            //List<byte[][]> ListLut = new List<byte[][]>();
            //for (int IdxChannel = 0; IdxChannel < this.AssociatedImage.NumChannels; IdxChannel++)
            //{
            //    UserControlSingleLUT SingleLUT = (UserControlSingleLUT)this.LUTManager.panelForLUTS.Controls[IdxChannel];
            //    if (SingleLUT.checkBoxIsActive.Checked == false) continue;

            //    ListLut.Add(SingleLUT.SelectedLUT);
            //}
            //ConvertImageFloatToRGB(AssociatedImage, 0, 255, ListLut, 0);
            #endregion
            
            // Declare an array to hold the bytes of the bitmap. 
            int bytes = scanline * NewHeight;
            byte[] rgbValues = new byte[bytes];

            // Copy the RGB values into the array.
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

  

            for (int IdxChannel = 0; IdxChannel < this.AssociatedImage.GetNumChannels(); IdxChannel++)
            {
                UserControlSingleLUT SingleLUT = (UserControlSingleLUT)this.LUTManager.panelForLUTS.Controls[IdxChannel];
                if (SingleLUT.checkBoxIsActive.Checked == false) continue;

                byte[][] CurrentLUT = SingleLUT.SelectedLUT;
                //ConvertImageFloatToRGB(AssociatedImage, 0, 255, SingleLUT.SelectedLUT, 0);
                if (GammaList[IdxChannel] != 1)
                {
                    for (int FullY = 0; FullY < NewHeight; FullY++)
                    {
                        RealY = (int)(FullY / ZoomFactor) + NewStartY;
                        if (RealY >= AssociatedImage.Height) RealY = AssociatedImage.Height - 1;

                        for (int FullX = 0; FullX < NewWidth; FullX++)
                        {
                            RealX = (int)(FullX / ZoomFactor) + NewStartX;
                            if (RealX >= AssociatedImage.Width) RealX = AssociatedImage.Width - 1;

                            float Value = AssociatedImage.SingleChannelImage[IdxChannel].Data[RealX + RealY * AssociatedImage.Width + ZPos * AssociatedImage.SliceSize];


                            Value = (float)Math.Pow(Value, GammaList[IdxChannel]);


                            int ConvertedValue = (int)((((CurrentLUT[0].Length - 1) * (Value - Min[IdxChannel])) / (Max[IdxChannel] - Min[IdxChannel])));

                            if (ConvertedValue < 0) ConvertedValue = 0;
                            if (ConvertedValue >= CurrentLUT[0].Length) ConvertedValue = CurrentLUT[0].Length - 1;

                            CurrentRed = (byte)CurrentLUT[0][ConvertedValue];
                            CurrentGreen = (byte)CurrentLUT[1][ConvertedValue];
                            CurrentBlue = (byte)CurrentLUT[2][ConvertedValue];


                            double NewValue = rgbValues[3 * FullX + FullY * scanline] + CurrentBlue;
                            if (NewValue > 255)
                                rgbValues[3 * FullX + FullY * scanline] = 255;
                            else
                                rgbValues[3 * FullX + FullY * scanline] += CurrentBlue;

                            NewValue = rgbValues[3 * FullX + 1 + FullY * scanline] + CurrentGreen;
                            if (NewValue > 255)
                                rgbValues[3 * FullX + 1 + FullY * scanline] = 255;
                            else
                                rgbValues[3 * FullX + 1 + FullY * scanline] += CurrentGreen;

                            NewValue = rgbValues[3 * FullX + 2 + FullY * scanline] + CurrentRed;
                            if (NewValue > 255)
                                rgbValues[3 * FullX + 2 + FullY * scanline] = 255;
                            else
                                rgbValues[3 * FullX + 2 + FullY * scanline] += CurrentRed;
                        }
                    }

                }
                else
                {
                    for (int FullY = 0; FullY < NewHeight; FullY++)
                    {
                        RealY = (int)(FullY / ZoomFactor) + NewStartY;
                        if (RealY >= AssociatedImage.Height) RealY = AssociatedImage.Height - 1;

                        for (int FullX = 0; FullX < NewWidth; FullX++)
                        {
                            RealX = (int)(FullX / ZoomFactor) + NewStartX;
                            if (RealX >= AssociatedImage.Width) RealX = AssociatedImage.Width - 1;

                            float Value = AssociatedImage.SingleChannelImage[IdxChannel].Data[RealX + RealY * AssociatedImage.Width + ZPos * AssociatedImage.SliceSize];

                            int ConvertedValue = (int)((((CurrentLUT[0].Length - 1) * (Value - Min[IdxChannel])) / (Max[IdxChannel] - Min[IdxChannel])));

                            if (ConvertedValue < 0) ConvertedValue = 0;
                            if (ConvertedValue >= CurrentLUT[0].Length) ConvertedValue = CurrentLUT[0].Length - 1;

                            CurrentRed = (byte)CurrentLUT[0][ConvertedValue];
                            CurrentGreen = (byte)CurrentLUT[1][ConvertedValue];
                            CurrentBlue = (byte)CurrentLUT[2][ConvertedValue];


                            double NewValue = rgbValues[3 * FullX + FullY * scanline] + CurrentBlue;
                            if (NewValue > 255)
                                rgbValues[3 * FullX + FullY * scanline] = 255;
                            else
                                rgbValues[3 * FullX + FullY * scanline] += CurrentBlue;

                            NewValue = rgbValues[3 * FullX + 1 + FullY * scanline] + CurrentGreen;
                            if (NewValue > 255)
                                rgbValues[3 * FullX + 1 + FullY * scanline] = 255;
                            else
                                rgbValues[3 * FullX + 1 + FullY * scanline] += CurrentGreen;

                            NewValue = rgbValues[3 * FullX + 2 + FullY * scanline] + CurrentRed;
                            if (NewValue > 255)
                                rgbValues[3 * FullX + 2 + FullY * scanline] = 255;
                            else
                                rgbValues[3 * FullX + 2 + FullY * scanline] += CurrentRed;
                        }
                    }
                }
            }
            // Copy the RGB values back to the bitmap
            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);

            // Unlock the bits.
            BT.UnlockBits(bmpData);

            // Draw the modified image.
            ThisGraph.DrawImage(BT, this.StartViewX, this.StartViewY);
            DrawLayers(ZoomFactor);
        }

        public Bitmap ConvertImageFloatToRGB(cImage ImageFloat, float Min, float Max, List<byte[][]> ListSelectedLUTs, int Z)
        {
            Bitmap BMP = new Bitmap(ImageFloat.Width, ImageFloat.Height, PixelFormat.Format24bppRgb);
            BitmapData bData = BMP.LockBits(new Rectangle(0, 0, ImageFloat.Width, ImageFloat.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            /*the size of the image in bytes */
            int size = bData.Stride * bData.Height;

            /*Allocate buffer for image*/
            byte[] ConvertedValues = new byte[size];
            
            int Zpos = Z * ImageFloat.Width * ImageFloat.Height;
            int Ypos;
           
            float MAXMIN = Max - Min;
            double NewValue;
            byte CurrentRed;
            byte CurrentGreen;
            byte CurrentBlue;

            for (int Channel = 0; Channel < ImageFloat.GetNumChannels(); Channel++)
            {
                byte[][] SelectedLUT = ListSelectedLUTs[Channel];
                int LUTLength = SelectedLUT[0].Length - 1;
                for (int j = 0; j < ImageFloat.Height; j++)
                {
                    Ypos = j * AssociatedImage.Width;
                    for (int i = 0; i < ImageFloat.Width; i++)
                    {
                        float Value = ImageFloat.SingleChannelImage[Channel].Data[i + Ypos + Zpos];
                        int ConvertedValue = (int)((LUTLength * (Value - Min)) / MAXMIN);
                        if (ConvertedValue < 0) ConvertedValue = 0;
                        else if (ConvertedValue > LUTLength) ConvertedValue = LUTLength;

                        CurrentRed = (byte)SelectedLUT[0][ConvertedValue];
                        CurrentGreen = (byte)SelectedLUT[1][ConvertedValue];
                        CurrentBlue = (byte)SelectedLUT[2][ConvertedValue];

                        NewValue = ConvertedValues[i * 3 + j * bData.Stride] + CurrentBlue;
                        if (NewValue > 255)
                            ConvertedValues[i * 3 + j * bData.Stride] = 255;
                        else
                            ConvertedValues[i * 3 + j * bData.Stride] += CurrentBlue;

                        NewValue = ConvertedValues[i * 3 + j * bData.Stride + 1] + CurrentGreen;
                        if (NewValue > 255)
                            ConvertedValues[i * 3 + j * bData.Stride + 1] = 255;
                        else
                            ConvertedValues[i * 3 + j * bData.Stride + 1] += CurrentGreen;

                        NewValue = ConvertedValues[i * 3 + j * bData.Stride + 2] + CurrentRed;
                        if (NewValue > 255)
                            ConvertedValues[i * 3 + j * bData.Stride + 2] = 255;
                        else
                            ConvertedValues[i * 3 + j * bData.Stride + 2] += CurrentRed;


                        //for (int RGBIdx = 0; RGBIdx < 3; RGBIdx++)
                        //{

                        //    NewValue = (ConvertedValues[i * 3 + j * bData.Stride + RGBIdx] + ConvertedValue);
                        //    if (NewValue >= LUTLength) NewValue = LUTLength - 1;

                        //    // now go through the LUT
                        //    //ConvertedValues[i * 3 + j * bData.Stride + 0] = SelectedLUT[2][NewValue];
                        //    //ConvertedValues[i * 3 + j * bData.Stride + 1] = SelectedLUT[1][NewValue];
                        //    ConvertedValues[i * 3 + j * bData.Stride + RGBIdx] = SelectedLUT[RGBIdx][NewValue];
                        //}

                        //ConvertedValues[i * 3 + j * bData.Stride + Channel] = (byte)NewValue;
                    }
                }
            }
          
            //for (int j = 0; j < ImageFloat.Height; j++)
            //{
            //    Ypos = j * AssociatedImage.Width;
            //    for (int i = 0; i < ImageFloat.Width; i++)
            //    {
            //        BMP.SetPixel(i, j, Color.FromArgb(SelectedLUT[0][ConvertedValues[i+Ypos]],
            //                               SelectedLUT[1][ConvertedValues[i + Ypos]],
            //                               SelectedLUT[2][ConvertedValues[i + Ypos]]));
            //    }
            //}


            /*This overload copies data of /size/ into /data/ from location specified (/Scan0/)*/
            //System.Runtime.InteropServices.Marshal.Copy(bData.Scan0, ConvertedValues, 0, size);

            //for (int i = 0; i < size; i += bitsPerPixel / 8)
            //{
            //    double magnitude = 1 / 3d * (ConvertedValues[i] + ConvertedValues[i + 1] + ConvertedValues[i + 2]);

            //    //data[i] is the first of 3 bytes of color

            //}

            /* This override copies the data back into the location specified */
            System.Runtime.InteropServices.Marshal.Copy(ConvertedValues, 0, bData.Scan0, ConvertedValues.Length);

            BMP.UnlockBits(bData);




            Form1 F = new Form1();
            F.pictureBox1.Image = BMP;
            F.ShowDialog();
     return BMP;
        }

        protected List<cObjectForAnnotation> ListObjectForNotations = new List<cObjectForAnnotation>();

        void DrawLayers(float ZoomFactor)
        {
            // ThisGraph = panelForImage.CreateGraphics();
            //foreach (cObjectForAnnotation TmpObj in ListObjectForNotations)
            //{
            //    if (TmpObj.GetType() == typeof(cString))
            //        ThisGraph.DrawString(((cString)TmpObj).Text, new Font(FontFamily.GenericSansSerif, ((cString)TmpObj).Size), new SolidBrush(((cString)TmpObj).ObjectColor), ((cString)TmpObj).PosX, ((cString)TmpObj).PosY);

            //    if (TmpObj.GetType() == typeof(cDisk))
            //        ThisGraph.FillEllipse(new SolidBrush(((cDisk)TmpObj).ObjectColor), ((cDisk)TmpObj).PosX, ((cDisk)TmpObj).PosY, ((cDisk)TmpObj).Size / 2, ((cDisk)TmpObj).Size / 2);
            //}

            foreach (cObjectForAnnotation TmpObj in ListObjectForNotations)
            {
                if (TmpObj.GetType() == typeof(cString))
                {
                    cString CurrentString  = ((cString)TmpObj);
                    ThisGraph.DrawString(CurrentString.Text, 
                        new Font(FontFamily.GenericSansSerif, CurrentString.Size), 
                        new SolidBrush(CurrentString.ObjectColor),
                        CurrentString.PosX * ZoomFactor,
                        CurrentString.PosY * ZoomFactor);

                }
                if (TmpObj.GetType() == typeof(cDisk))
                {

                    cDisk CurrentDisk = ((cDisk)TmpObj);

                    Brush NewBrush = new SolidBrush(CurrentDisk.ObjectColor);
                    
                    float Width =  CurrentDisk.Size * ZoomFactor;
                    float Height = Width;
                    float PosX = CurrentDisk.PosX * ZoomFactor - Width / 2;
                    float PosY = CurrentDisk.PosY * ZoomFactor - Height / 2;


                    ThisGraph.FillEllipse(NewBrush, PosX , PosY , Width , Height);
                }
            }


        }

        private void FormForImageDisplay_Scroll(object sender, ScrollEventArgs e)
        {
            this.StartViewX = this.HorizontalScroll.Value;
            this.StartViewY = this.VerticalScroll.Value;
            DrawPic();

            //ThisGraph.DrawImage(BT, this.StartViewX, this.StartViewY);
            //DrawLayers(Zoom / 100.0f);
            //toolStripStatusLabelStartView.Text = "Start View: " + this.HorizontalScroll.Value + ":" + this.VerticalScroll.Value;
        }

        private void FormForImageDisplay_Resize(object sender, EventArgs e)
        {
            ViewDimX = this.Width - 46;
            ViewDimY = this.Height - 68;
            this.StartViewX = this.HorizontalScroll.Value;
            this.StartViewY = this.VerticalScroll.Value;
       
            DrawPic();

          //  this.panelForImage.Paint -= PaintEventHandler(panelForImage_Paint);

        }

        private void panelForImage_Paint(object sender, PaintEventArgs e)
        {
            if (BT != null)
            {
                ThisGraph.DrawImage(BT, this.StartViewX, this.StartViewY);
                DrawLayers(Zoom / 100.0f);

                using (Pen pen = new Pen(Color.Red, 2))
                {
                    e.Graphics.DrawRectangle(pen, mRect);
                }

            }



        }

        private void NavigatorToolStripMenuItem(object sender, EventArgs e)
        {
            if (this.ZNavigator == null)
                this.ZNavigator.Show();
            else
            {
                this.ZNavigator.Visible = true;
                this.ZNavigator.BringToFront();
            }
        }

        private void lUTManagerToolStripMenuItem(object sender, EventArgs e)
        {
            if (this.LUTManager == null)
                LUTManager.Show();
            else
            {
                this.LUTManager.Visible = true;
                this.LUTManager.BringToFront();
            }
        }

        private void FormForImageDisplay_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.LUTManager.Close();
            this.ZNavigator.Close();

            this.AssociatedImage.Dispose();
            //CurrentFormForImageDisplay
        }

    }
}
